<?php

namespace service\impl;

use service\exception\ServiceException;
use service\ext\PageData;
use service\service\UserSubjectStaticService;
use service\vo\user\UserSubjectStatic;
use think\db\exception\DbException;

class UserSubjectStaticServiceImpl extends BaseImpl implements UserSubjectStaticService
{
    private static string $modeName = 'userSubjectStatic';

    /**
     * @inheritDoc
     */
    public function addUserSubjectStatic(UserSubjectStatic $userSubjectStatic): int
    {
        // TODO: Implement addUserSubjectStatic() method.
        $data = [
            self::$FIELD_COMMON_U_ID => $userSubjectStatic->getUserId(),
            self::$FIELD_COMMON_SUBJECT_ID => $userSubjectStatic->getSubjectId(),
            self::$FIELD_USER_SUBJECT_STATIC_UPDATE_TIME => date("Y-m-d H:i:s"),
            self::$FIELD_USER_SUBJECT_STATIC_ADD_TIME => date("Y-m-d H:i:s"),
        ];

        return $this->getUserSubjectStaticDb($userSubjectStatic->getUserId())
            ->insertGetId($data);
    }

    /**
     * @inheritDoc
     */
    public function increaseUserSubjectStatic(int $userId, int $subjectId, int $times): int
    {
        // TODO: Implement increaseUserSubjectStatic() method.
        return $this->getUserSubjectStaticDb($userId)
            ->where(self::$FIELD_COMMON_U_ID, $userId)
            ->where(self::$FIELD_COMMON_SUBJECT_ID, $subjectId)
            ->inc(self::$FIELD_USER_SUBJECT_STATIC_TIMES, $times)
            ->update();
    }

    /**
     * @inheritDoc
     *
     * @throws DbException
     * @throws ServiceException
     */
    public function getUserSubjectStaticByUserIdAndSubjectId(int $userId, int $subjectId): UserSubjectStatic
    {
        // TODO: Implement getUserSubjectStaticByUserIdAndSubjectId() method.
        $po = $this->getUserSubjectStaticDb($userId)
            ->where(self::$FIELD_COMMON_U_ID, $userId)
            ->where(self::$FIELD_COMMON_SUBJECT_ID, $subjectId)
            ->find();
        if(empty($po)){
            throw new ServiceException(self::$modeName, self::ERROR_DATA_NOT_EXISTS);
        }

        return $this->getUserSubjectStaticVoFromPo($po);
    }

    /**
     * @inheritDoc
     * @throws DbException
     */
    public function getUserSubjectStaticByUserIdAndSubjectIds(int $userId, array $subjectIds): array
    {
        // TODO: Implement getUserSubjectStaticByUserIdAndSubjectIds() method.
        $voArr = [];
        $poArr = $this->getUserSubjectStaticDb($userId)
            ->where(self::$FIELD_COMMON_U_ID, $userId)
            ->whereIn(self::$FIELD_COMMON_SUBJECT_ID, $subjectIds)
            ->select();
        foreach ($poArr as $po){
            $voArr[] = $this->getUserSubjectStaticVoFromPo($po);
        }
        return $voArr;
    }

    /**
     * @inheritDoc
     * @throws DbException
     * @throws ServiceException
     */
    public function searchUserSubjectStatic(int $currentPage, int $pageSize, array $filterCriteria, array $sorterCriteria): PageData
    {
        // TODO: Implement searchUserSubjectStatic() method.
        if(empty($filterCriteria[self::$FILTER_USER_ID])){
            throw new ServiceException(self::$modeName, self::ERROR_USER_ID);
        }
        $userId = $filterCriteria[self::$FILTER_USER_ID];
        $filter = [];
        if (!empty($filterCriteria)) {
            foreach ($filterCriteria as $key => $value) {
                if (strcasecmp($key, self::$FILTER_USER_ID) == 0) {
                    //用户id
                    $filter[] = [self::$FIELD_COMMON_U_ID, "=", $value];
                } else if (strcasecmp($key, self::$FILTER_SUBJECT_ID) == 0) {
                    //习题id
                    $filter[] = [self::$FIELD_COMMON_SUBJECT_ID, "=", $value];
                }
            }
        }

        //构建排序条件
        $sort = [];
        if (!empty($sorterCriteria)) {
            foreach ($sorterCriteria as $key => $value) {
                if (strcasecmp($key, self::$SORT_ID) == 0) {
                    $sort[self::$FIELD_COMMON_ID] = $value ? self::$SORT_VALUE_ASC : self::$SORT_VALUE_DESC;
                }
            }
        }

        $count = $this->getUserSubjectStaticDb($userId)
            ->where($filter)
            ->count();
        $list = $this->getUserSubjectStaticDb($userId)
            ->where($filter)
            ->order($sort)
            ->limit($pageSize)
            ->page($currentPage)
            ->select();


        $dataList = [];
        foreach ($list as $po) {
            $dataList[] = $this->getUserSubjectStaticVoFromPo($po);
        }

        $pageData = new PageData();
        $pageData->setData($dataList);
        $pageData->setCount($count);

        return $pageData;
    }

    private function getUserSubjectStaticVoFromPo($po): UserSubjectStatic
    {
        $vo = new UserSubjectStatic();
        $vo->setUserId($po[self::$FIELD_COMMON_U_ID]);
        $vo->setSubjectId($po[self::$FIELD_COMMON_SUBJECT_ID]);
        $vo->setId($po[self::$FIELD_COMMON_ID]);
        $vo->setAddTime($po[self::$FIELD_USER_SUBJECT_STATIC_ADD_TIME]);
        $vo->setTimes($po[self::$FIELD_USER_SUBJECT_STATIC_TIMES]);
        $vo->setUpdateTime($po[self::$FIELD_USER_SUBJECT_STATIC_UPDATE_TIME]);
        return $vo;
    }
}